﻿using System;
using System.Threading;
using System.Collections;
using System.Linq;
using System.Text;

namespace Zadanie3
{
    public delegate void ChangedEventHandler();

    class TollHouses
    {
        public enum Direction { NORTHBOUND, SOUTHBOUND };

        public event ChangedEventHandler Changed;

        private int northbound = 0;
        public int Northbound
        {
            get
            {
                return northbound;
            }
        }
        private int southbound = 0;
        public int Southbound
        {
            get
            {
                return southbound;
            }
        }

        public void Enter(Direction direction)
        {
            lock (this)
            {
                if (!ConditionVariable(direction)) Monitor.Wait(this);
                IncreaseCarCounter(direction);
                if (Changed != null) Changed();
            }
        }

        public void Leave(Direction direction)
        {
            lock (this)
            {
                DecreaseCarCounter(direction);
                if(ConditionVariable(AnotherDirection(direction))) Monitor.PulseAll(this);
                if (Changed != null) Changed();
            }
        }

        private void IncreaseCarCounter(Direction direction)
        {
            switch (direction)
            {
                case Direction.NORTHBOUND:
                    northbound++;
                    break;
                case Direction.SOUTHBOUND:
                    southbound++;
                    break;
            }
        }

        private void DecreaseCarCounter(Direction direction)
        {
            switch (direction)
            {
                case Direction.NORTHBOUND:
                    northbound--;
                    break;
                case Direction.SOUTHBOUND:
                    southbound--;
                    break;
            }
        }

        private bool ConditionVariable(Direction direction)
        {
            return direction == Direction.NORTHBOUND ? southbound == 0 : northbound == 0;
        }

        private Direction AnotherDirection(Direction direction)
        {
            return direction == Direction.NORTHBOUND ? Direction.SOUTHBOUND : Direction.NORTHBOUND;
        }
    }
}
